package pri.black.garden.controller;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Arrays;

import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import pri.black.dogview.domain.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import pri.black.dogview.util.DateUtils;
import pri.black.dogview.util.HolidayUtils;
import pri.black.garden.biz.*;
import pri.black.garden.domain.*;
import pri.black.garden.domain.vo.WeekPlanVO;
import pri.black.garden.service.IPlanService;

/**
 * planController
 * 
 * @author black
 * @date 2025-02-16
 */
@Slf4j
@RestController
@RequestMapping("/garden/plan")
public class PlanController
{
    @Autowired
    private PlanBiz planBiz;
    @Autowired
    private PlanLinkBiz planLinkBiz;
    @Autowired
    private BlockBiz blockBiz;

    @Autowired
    private PlanLinkVegetablesBiz planLinkVegetablesBiz;

    @Autowired
    private VegetablesBiz vegetablesBiz;

    /**
     * 查询plan列表
     */
    //@PreAuthorize("@ss.hasPermi('garden:plan:list')")
    @GetMapping("/list")
    public R list(Plan query)
    {
        List<Plan> list = planBiz.getService()
                .lambdaQuery()
                .like(query.getName() != null && !query.getName().isEmpty(), Plan::getName, query.getName())
                .orderByDesc(Plan::getId).list();
        for (Plan record : list) {
            handleQueryResults(record);
            if (record.getPid() == null) {
                record.setPid(0L);
            }
        }
        return R.ok(list);
    }

    @GetMapping("/tasks")
    public R tasks(Plan query)
    {
        List<Plan> list = planBiz.getService()
                .lambdaQuery()
                .like(query.getName() != null && !query.getName().isEmpty(), Plan::getName, query.getName())
                .eq(Plan::getState,0)
                .orderByDesc(Plan::getPlanStart).list();
        for (Plan record : list) {
            handleQueryResults(record);
            if (record.getPid() == null) {
                record.setPid(0L);
            }
        }
        List<Plan> tasks = new LinkedList<>();
        tasks.addAll(list);
        return R.ok(tasks);
    }

    @GetMapping("weeks")
    public R weeks(@RequestParam(value = "month",required = false) Integer month){
        List<Plan> plans = planBiz.getService().list();

        LocalDate now = LocalDate.now();


        LocalDate start = LocalDate.of(now.getYear(), now.getMonthValue(), 1);

        if (month != null) {
            start = start.plusMonths(month);
        }


        LocalDate end = start.plusMonths(1);
        int value = start.getDayOfWeek().getValue();
        LocalDate weekStart = start.minusDays(value - 1);


        log.debug("plus before {}",weekStart);
        LocalDate lastWeekDay = weekStart.plusDays(7 * 5 -1);
        log.debug("plus after {}",weekStart);
        if (weekStart.getDayOfYear() == lastWeekDay.getDayOfYear()) {
            throw new RuntimeException("localdate 被修改");
        }
        LocalDate iterator = weekStart.plusDays(0);
        List<List<WeekPlanVO>> rows = new ArrayList<>();
        List<WeekPlanVO> weekPlanVOS = null;

        HolidayUtils holidayUtils = new HolidayUtils();

        int weekIndex = 0;
        while (!iterator.isAfter(lastWeekDay)) {
            if (weekIndex % 7 == 0) {
                weekPlanVOS = new LinkedList<>();
                rows.add(weekPlanVOS);
            }
            weekIndex ++;
            WeekPlanVO weekPlanVO = new WeekPlanVO(iterator);
            weekPlanVO.setToday(iterator.equals(now));
            weekPlanVO.setHoliday(holidayUtils.in(iterator));
            weekPlanVOS.add(weekPlanVO);

            for (Plan plan : plans) {
                if (DateUtils.in(iterator, plan.getPlanStart(), plan.getPlanEnd())) {
                    weekPlanVO.addPlan(plan);
                }
            }
            iterator = iterator.plusDays(1);
        }
        return R.ok(rows);
    }

    @GetMapping("all")
    public R all(){
        return R.ok(planBiz.getService().list());
    }

    private void handleQueryResults(Plan record) {
        List<PlanLink> planLinks = planLinkBiz.getService().lambdaQuery().eq(PlanLink::getPlanId, record.getId()).list();
        if (planLinks.isEmpty()) {

        }else {
            List<Long> ids = planLinks.stream().map(PlanLink::getBlockId).toList();
            record.setBlockIds(ids);
            if (record.getBlockIds() != null && !record.getBlockIds().isEmpty()) {
                List<Block> blocks = blockBiz.getService().lambdaQuery().in(Block::getId, record.getBlockIds()).list();
                for (Block block : blocks) {
                    block.setParent(blockBiz.getService().getById(block.getPid()));
                }
                record.setBlocks(blocks);
            }
        }


        List<PlanLinkVegetables> list = planLinkVegetablesBiz.getService().lambdaQuery().eq(PlanLinkVegetables::getPlanId, record.getId()).list();
        record.setPlantIds(list.stream().map(PlanLinkVegetables::getPlantId).toList());

        if (record.getPlantIds() != null && !record.getPlantIds().isEmpty()) {
            List<Vegetables> plants = vegetablesBiz.getService().lambdaQuery().in(Vegetables::getId, record.getPlantIds()).list();
            record.setPlants(plants);
        }
    }

    /**
     * 获取plan详细信息
     */
    //@PreAuthorize("@ss.hasPermi('garden:plan:query')")
    @GetMapping(value = "/{id}")
    public R getInfo(@PathVariable("id") Long id)
    {
        return R.ok(planBiz.getService().getById(id));
    }

    /**
     * 新增plan
     */
    //@PreAuthorize("@ss.hasPermi('garden:plan:add')")
    //@Log(title = "plan", businessType = BusinessType.INSERT)
    @PostMapping
    public R add(@RequestBody Plan plan)
    {
        return R.ok(planBiz.save(plan));
    }

    /**
     * 修改plan
     */
    //@PreAuthorize("@ss.hasPermi('garden:plan:edit')")
    //@Log(title = "plan", businessType = BusinessType.UPDATE)
    @PutMapping
    public R edit(@RequestBody Plan plan)
    {
        return R.ok(planBiz.update(plan));
    }

    /**
     * 删除plan
     */
    //@PreAuthorize("@ss.hasPermi('garden:plan:remove')")
    //@Log(title = "plan", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public R remove(@PathVariable("ids") Long[] ids)
    {
        return R.ok(planBiz.getService().removeByIds(Arrays.asList(ids)));
    }

    @GetMapping("/query-by-block")
    public R queryByBlock(@RequestParam("block") Long blockId) {
        List<PlanLink> list = planLinkBiz.getService().lambdaQuery().eq(PlanLink::getBlockId, blockId).list();
        if (!list.isEmpty()) {
            List<Long> planIds = list.stream().map(PlanLink::getPlanId).toList();
            List<Plan> rows = planBiz.getService().lambdaQuery().in(Plan::getId, planIds).list();
            for (Plan row : rows) {
                handleQueryResults(row);
            }
            return R.ok(rows);
        }else {
            return R.ok(new LinkedList<>());
        }
    }
}
